from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import viewsets
from apps.oaauth.serializers import UserSerializer
from .serializers import AddstaffSerializer,UploadStaffSerializer
from apps.oaauth.models import OAAbstractUser,UserStatusChoices,OADepartment
from django.core.mail import send_mail
from django.conf import settings
from utils import aeser
from django.urls import reverse
from oaback.celery import test_task
from .task import send_mail_task
from django.views import View
from django.shortcuts import render
from django.http.response import JsonResponse
from  urllib import parse
from apps.absent.page import MyModelPagination
import json
import pandas as pd
from django.http.response import HttpResponse
from django.db import transaction
from rest_framework.permissions import IsAuthenticated, IsAdminUser,AllowAny

# 邮件激活用户信息
class ActiveStaffView(View):
    permission_classes = [AllowAny]
    def get(self,request):
        #获取token并存储在cookie中
        token = request.GET.get('token')
        # token = "1HudaYybX3bQUZhLfkvzUg=="
        response = render(request, 'active.html')
        response.set_cookie('token', token)
        return response
    def post(self,request):
        try:
            # 解密token(邮箱）
            token = request.COOKIES.get('token')
            aes = aeser.AESCipher(settings.SECRET_KEY)
            email = aes.decrypt(token)
            # 表单邮箱
            form_email = request.POST.get('email')
            password = request.POST.get('password')
            user = OAAbstractUser.objects.filter(email=form_email).first()
            if not user or not user.check_password(password):
                return JsonResponse({'code':400,'msg':'邮箱或密码错误'})
            else:
                if email != form_email:
                    return JsonResponse({'code':400,'msg':'邮箱不一致'})
                user.status = 1
                user.save()
                return JsonResponse({'code':200,'msg':'激活成功'})
        except:
            return JsonResponse({'code':400,'msg':'激活失败'})






# 添加员工
class staffView(APIView):
    def post(self,request):
        # APIView需要传context，viewset视图集不用传
        serializer = AddstaffSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            email = serializer.validated_data.get('email')
            realname = serializer.validated_data.get('realname')
            password = serializer.validated_data.get('password')
            #创建普通用户create_user，超级用户create_superuser
            user = OAAbstractUser.objects.create_user(email=email,realname=realname,password=password)
            department = request.user.department
            user.department = department
            # user.status = 1
            user.save()

            # 发送激活邮件
            self.send_active_email(email)
            return Response({'msg': '创建成功,请查看邮箱激活'}, status=status.HTTP_201_CREATED)

        else:
            return Response({'msg': list(serializer.errors.values())[0][0]}, status=status.HTTP_400_BAD_REQUEST)
    # 发送邮件
    def send_active_email(self,email):
        # 为了区分用户，在发送的链接中要包含用户的邮箱  要加密：AES
        aes = aeser.AESCipher(settings.SECRET_KEY)
        token = aes.encrypt(email)
        # 这个名称staff: activestaff应该在你的urls.py中通过name = "activestaff"指定过，并且属于staff这个app的namespace
        # 对应激活接口url:api/staff/active/?token=xxx
        active_path = reverse("staff:activestaff") + "?" + parse.urlencode({"token":  token})
        active_url = self.request.build_absolute_uri(active_path)
        # 发送邮件  发送一个链接让用户激活
        message = f'点击以下链接激活账号：{active_url}'
        subject = f'账号激活'
        # send_mail(subject=subject,   #题目
        #           recipient_list=[email],  # 收件人
        #           message=message,   # 邮件内容
        #           from_email=settings.DEFAULT_FROM_EMAIL)   # 发件人
        #使用celery异步执行发送邮件
        send_mail_task.delay(email,message,subject)

# 员工列表
class stafflistViewSet(viewsets.ModelViewSet):
    queryset = OAAbstractUser.objects.all()
    serializer_class = UserSerializer
    pagination_class = MyModelPagination
    def get_queryset(self):
        queryset = self.queryset
        department_id = self.request.query_params.get('department_id')
        realname = self.request.query_params.get('realname')
        if department_id:
            queryset = queryset.filter(department_id=department_id)
        if realname:
            queryset = queryset.filter(realname__contains=realname)
        return queryset
    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset().order_by('date_joined')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

import traceback
# 下载功能 下载员工信息到Excel
class staffDownloadView(APIView):
    def get(self,request):
        #传如"[25]"->json字符串
        ids = request.query_params.get('ids')
        try:
            ids = json.loads(ids)
        except:
            return Response({'msg':'参数错误'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(ids, list):
            return Response({'msg': 'ids 参数必须为'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            user = request.user
            queryset = OAAbstractUser.objects.all()
            #只有董事会或部门领导可以下载
            if user.department.name != '董事会':
                if user.department.leader.id != user.id:
                    return Response({'msg':'权限不足'}, status=status.HTTP_403_FORBIDDEN)
            queryset = queryset.filter(id__in=ids)
            result = queryset.values('email', 'realname', 'department__name', 'status')
            df = pd.DataFrame(list(result))
            df.rename(columns={'realname':'姓名','email':'邮箱','department__name': '部门',  'status': '状态'}, inplace=True)
            # 下载为Excel
            response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename="员工信息.xlsx"'
            #把df写入到Response中
            with pd.ExcelWriter(response,engine='openpyxl') as writer:
                df.to_excel(writer, sheet_name='员工信息', index=False)
            return response
        except Exception as e:
            print("导出失败异常：", str(e))
            traceback.print_exc()  # 打印详细堆栈
            return Response({'msg': '下载失败', 'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class staffUploadView(APIView):
    def post(self, request):
        serializer = UploadStaffSerializer(data=request.data)
        if not serializer.is_valid():
            return Response({'msg': list(serializer.errors.values())[0][0]}, status=status.HTTP_400_BAD_REQUEST)

        try:
            file = serializer.validated_data.get('file')
            current_user = request.user

            # 检查部门和领导信息是否完整
            if current_user.department.name != '董事会' :
                if current_user.department.leader.id != current_user.id:
                    return Response({'msg': '权限不足'}, status=status.HTTP_403_FORBIDDEN)

            try:
                df = pd.read_excel(file)
            except Exception as e:
                return Response({'msg': 'Excel文件读取失败，请检查文件格式'}, status=status.HTTP_400_BAD_REQUEST)

            # 校验是否包含必需的列
            required_columns = ['部门', '邮箱', '姓名']
            for col in required_columns:
                if col not in df.columns:
                    return Response({'msg': f'Excel中缺少列：{col}'}, status=status.HTTP_400_BAD_REQUEST)

            users = []

            for index, row in df.iterrows():
                try:
                    department = OADepartment.objects.filter(name=row['部门']).first()
                    if not department:
                        return Response({'msg': f"第{index+1}行：部门不存在"}, status=status.HTTP_400_BAD_REQUEST)

                    email = row['邮箱']
                    realname = row['姓名']
                    password = "123456"

                    user = OAAbstractUser(
                        email=email,
                        realname=realname,
                        department=department,
                        status=UserStatusChoices.UNACTIVE
                    )
                    user.set_password(password)
                    users.append(user)
                except Exception as e:
                    return Response({'msg': f"第{index+1}行数据格式错误：{str(e)}"}, status=status.HTTP_400_BAD_REQUEST)

            # 原子操作：批量创建用户
            with transaction.atomic():
                OAAbstractUser.objects.bulk_create(users)

            return Response({'msg': '员工导入成功'}, status=status.HTTP_201_CREATED)

        except Exception as e:
            traceback.print_exc()
            return Response({'msg': f'服务器错误: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)




#  测试celery
class TestCeleryView(APIView):
    def get(self,request):
        test_task.delay()
        return Response({'msg':'发送成功'})